﻿//********************************************************************************//
//		功能名称:	UART发送（单一byte数据）
//		功能编号:	070101
//		适应芯片:	适用于所有芯片
//--------------------------------------------------------------------------------//
//程序说明:
//	通过设置UART时钟、波特率等来设置通讯速度
//	时钟推荐使用1M、2M、4M、8M，时钟越高，LVR设置需求越高
//	在使用时程序会将系统时钟切到UART时钟，等数据传输完毕，再切回原来的系统时钟
//注意事项:
//	1.案例为PMS154C，其他芯片原理都相同
//	2.UART时钟选择其他时请自行修改Clock_Adjust()中的程序及相应的CLKMD
//********************************************************************************//
#include	"extern.h"
#include 	"lib_func.C"

/********************************************************************************************************************
											Macro definition
*********************************************************************************************************************/

#define POWER_VCC_CHECK_IO		 	PA.5
#define POWER_CHARGE_CHECK_IO		PB.7
// #define POWER_STDBY_CHECK_IO		PA.X

#define FAN_ENABLE_IO				PB.2
#define FAN_INSTALL_FB_IO			PB.0
#define FAN_PWM_IO					PB.4

#define COOL_SWITCH_IO				PB.5


#define DEF_SET_BIT0                0x01
#define DEF_SET_BIT1                0x02
#define DEF_SET_BIT2                0x04
#define DEF_SET_BIT3                0x08
#define DEF_SET_BIT4                0x10
#define DEF_SET_BIT5                0x20
#define DEF_SET_BIT6                0x40
#define DEF_SET_BIT7                0x80

#define DEF_CLR_BIT0                0xFE
#define DEF_CLR_BIT1                0xFD
#define DEF_CLR_BIT2                0xFB
#define DEF_CLR_BIT3                0xF7
#define DEF_CLR_BIT4                0xEF
#define DEF_CLR_BIT5                0xDF
#define DEF_CLR_BIT6                0xBF
#define DEF_CLR_BIT7                0x7F

#define UART_ENABLE			0

#define GEAR_TO_NUM0		0
#define GEAR_TO_NUM1		1
#define GEAR_TO_NUM25		25
#define GEAR_TO_NUM50		50
#define GEAR_TO_NUM75		75
#define GEAR_TO_NUM100		100

#define GEAR_TO_CLOSE		101
#define GEAR_LIMIT_NUM40	40

#define GEAR_PWM_NUM		150		//


/********************************************************************************************************************
											Variable definition
*********************************************************************************************************************/

/* 通用变量 */
byte temp_value = 0;
byte temp_count = 0;
eword temp_value32 = 0;
word flags = 0;
/* 工作状态 */
bit fan_open_flag : flags.0;
bit key1_one_flag : flags.1;
bit key1_long_flag : flags.2;
bit key2_one_flag : flags.3;
bit key2_long_flag : flags.4;
bit key3_one_flag : flags.5;
bit key3_long_flag : flags.6;
bit update_gear_flag : flags.7;
byte work_gear_num = 0;
byte record_pwm = 0;
bit cool_work_mode : flags.8;
byte record_work_gear = 0;

/* 电量相关 */
bit blink_flag : flags.10;
bit charge_status_flag : flags.11;
bit update_consume_time_flag : flags.12;
byte charge_status = 0;
byte power_alarm = 0;
word battery_voltage_rate = 0;
word blink_interval = 0;
word gear_show_time = 0;
byte fan_low_check_num = 0;
byte fan_check_count = 0;
byte fan_not_check_num = 0;

eword consume_power_interval_count = 0;
eword reload_consume_power_interval = 0;
eword reload_consume_power_back = 0;
eword charge_power_interval_count = 0;

word sleep_time_count = 0;
byte check_adc_delay = 0;



/********************************************************************************************************************
											Chip peripheral initailazation
*********************************************************************************************************************/

/*****************************************************************************
@brief 	：IO口初始化
@param    
@retval	    
******************************************************************************/
void	IO_init(void)
{
	//注：无PA.1,PA.2脚位
	//未使用端口需有防漏电设置，如加内部上拉
	PAPH	=	0b0000_0000;	//上拉控制寄存器，控制上拉高相应的引脚（1：启用，0：停用）
	PBPH	=	0b0000_0000;
	PAPL	=	0b0000_0000;	//下拉控制寄存器，下拉电阻使能寄存器位（1：启用，0：停用）
	PBPL	=	0b0000_0000;
	PAC		=	0b1111_1111;	//数据控制寄存器（1：输出模式，0：输入模式）
	PBC		=	0b1111_1111;
	PA		=	0b0000_0000;	//数据寄存器
	PB		=	0b0000_0000;
	.delay 10000;
	//单个IO输出配置，以PA0为例
//	$ PA.0 out,high;	//PA0输出高
//	PAC.0 = 1;PA.0 = 1;	//PA0输出高，寄存器配置
//	$ PA.0 out,low;		//PA0输出低
//	PAC.0 = 1;PA.0 = 0;	//PA0输出低，寄存器配置
	$ FAN_ENABLE_IO out,low;

	//单个IO输入配置，以PA4为例
//	$ PA.4 in,pull;					//PA4输入上拉
//	$ PA.4 in,PH;					//PA4输入开上拉
//	PAC.4 = 0;PAPH.4 = 1;			//PA4输入开上拉，寄存器配置
//	$ PA.4 in,X_PH;					//PA4输入关上拉
//	PAC.4 = 0;PAPH.4 = 0;			//PA4输入关上拉，寄存器配置

	$ POWER_VCC_CHECK_IO in;
	$ POWER_CHARGE_CHECK_IO in;
	// $ POWER_STDBY_CHECK_IO in,PH;
	$ FAN_INSTALL_FB_IO in;

	misc = 0b00100100;
}

/*****************************************************************************
@brief 	：通用16位定时器      
@param    
@retval	    
******************************************************************************/
word reload_T16 = 0;
void T16_Init(void)
{
	$ T16M SYSCLK,/16,BIT9;		//T16的时钟源选择，内部的时钟分频器，中断源选择（当选择位由低到高或者由高到低时，发生中断事件）；
								//时钟源选择可以选择STOP, SYSCLK, PA4_F, IHRC, EOSC, ILRC, PA0_F；分频器可选择/1, /4, /16, /64
								//中断源可选择BIT8, BIT9, BIT10, BIT11, BIT12, BIT13, BIT14, BIT15
	reload_T16 = 260; 			//386 500us	 260 1000us
				//计算公式为	[1/(时钟源/分频器)]*(中断源-reload_T16)=[1/(1M/16)]*(2^10-(1024-625))=0.01s

	stt16 reload_T16;			//设定计数器初始值reload_T16，当计数器累加超过设定中断源时产生中断;
	$ INTEGS BIT_R;				//T16中断边缘选择，上升缘请求中断为BIT_R，下降缘请求中断为BIT_F；默认为上升缘请求。
	//使用下面两句时，会关闭其他中断的设置，一般推荐使用对位操作的方法来驱动
//	$ INTEN T16;				//中断允许寄存器，启用从T16的溢出中断；1：启用，0：停用。
//	$ INTRQ T16;				//中断请求寄存器，此位是由硬件置位并由软件清零；1：请求，0：不请求。

	INTEN.T16 = 1;				//中断允许寄存器，开T16中断
//	INTEN.T16 = 0;				//中断允许寄存器，关T16中断
	INTRQ.T16 = 0;				//中断请求寄存器，清零INTRQ寄存器。
}

/*****************************************************************************
@brief	:Close T16 timer
@param    
@retval	    
******************************************************************************/
void	T16_stop(void)
{
	$ T16M stop;			//关闭T16时钟
	INTRQ.T16 = 0;			//关闭T16中断
	INTEN.T16 = 0;
}

/*****************************************************************************
@brief 	：用于输出pwm定时器的配置
@param    
@retval	    
******************************************************************************/
#define PWM_SET_IO		PB4
void TM2_PWM(void)
{
	TM2CT = 0;					//计数寄存器
	TM2B = 0;					//上限寄存器
	// $ TM2C IHRC*2,PWM_SET_IO,PWM;		//选择时钟源，输出脚，模式，是否反极性输出（写Inverse为启用，不写则为停用）
								//根据要求时钟可选择SYSCLK, EOSC, IHRC | IHRC*2（在执行中的code options中设置TMx_source）, ILRC等，输出脚可以选择Disable（不选择）, PB2, PB4, PA3，模式可选择PWM模式/定周期模式（Period）
								//例：系统时钟，PB2输出，PWM模式，无反极性；
	$ TM2C STOP;				//关掉时钟，即TM2停止工作
	$ TM2S 7bit,/1,/1;			//选择分辨率，预分频，分频
								//分辨率可选择8bit,6bit | 7bit（在执行中的code options中设置TMx_bit），预分频可选择/1, /4, /16, /64，分频可选择/1 ~ /32（对应TM2S[4:0]的00000 ~ 11111）								
}

/*****************************************************************************
@brief 	：用于输出pwm定时器的配置
@param    
@retval	    
******************************************************************************/
void TM3_PWM(void)
{
	TM3CT = 0;					//计数寄存器
	TM3B = 0;					//上限寄存器
	$ TM3C IHRC*2,PB5,PWM;		//选择时钟源，输出脚，模式，是否反极性输出（写Inverse为启用，不写则为停用）
								//根据要求时钟可选择SYSCLK, EOSC, IHRC | IHRC*2（在执行中的code options中设置TMx_source）, ILRC等，输出脚可以选择Disable（不选择）,，模式可选择PWM模式/定周期模式（Period）
								//例：系统时钟，PB2输出，PWM模式，无反极性；
	$ TM3C STOP;				//关掉时钟，即TM2停止工作
	$ TM3S 7bit,/1,/1;			//选择分辨率，预分频，分频
								//分辨率可选择8bit,6bit | 7bit（在执行中的code options中设置TMx_bit），预分频可选择/1, /4, /16, /64，分频可选择/1 ~ /32（对应TM2S[4:0]的00000 ~ 11111）
}

/********************************************************************************************************************
											This is general function
*********************************************************************************************************************/

/*****************************************************************************
@brief 	：除法运算
@param    
@retval	    
******************************************************************************/
DWORD	div_src4;
EWORD	div_val2, div_res2;
void	DWord_Div_Word (void)
{	//	div_src4[D] / div_val2[W]	=	div_src4[D] * div_val2[W] + div_res2[W]
	BYTE	div_cnt, div_tmp;
	div_cnt		=	0;
	div_res2	=	0;

	do
	{
		div_src4	<<=		1;
		div_res2	<<<=	1;
		div_tmp		<<<=	1;
		div_cnt++;
		A	=	(div_res2 - div_val2) >> 8;

		if (div_tmp.0 || ! CF)
		{
			div_res2$1	=	A;
			div_res2$0	-=	div_val2$0;
			div_src4.0	=	1;
		}
	} while (! div_cnt.5);
}

/*****************************************************************************
@brief 	：乘法运算
@param    
@retval	    
******************************************************************************/
DWORD	mul_t4;
EWORD	mul_x2;
EWORD	mul_y2;
void	Word_Mul_Word (void)
{	//	mul_t4[D]	=	mul_x2[W] * mul_y2[W]
	mul_t4$3	=	0;
	mul_t4$2	=	0;

	BYTE	cnt;
	cnt	=	16;

	do
	{
		mul_x2	>>=	1;
		if (CF)
		{
			mul_t4	+=	(mul_y2 << 16);
		}
		mul_t4	>>>= 1;
	} while (--cnt);
}

/*****************************************************************************
@brief 	：定时器延时
@param    
@retval	    
******************************************************************************/
word delay_time_count = 0;
void Delay_ms(word num)
{
	delay_time_count = num;
	while(delay_time_count)
	{
		
	}
}
/********************************************************************************************************************
   	   	   	   	   	   	   	   	   	   	   	This is the LED driver part
*********************************************************************************************************************/
#define BIT0   	0x01
#define BIT1   	0x02
#define BIT2   	0x04
#define BIT3   	0x08
#define BIT4   	0x10
#define BIT5   	0x20
#define BIT6   	0x40
#define BIT7   	0x80

#define LED_PORT1		PA.0
#define LED_PORT2		PA.4
#define LED_PORT3		PA.3
#define LED_PORT4		PB.3
#define LED_PORT5		PB.1 

#define ICON_SET_RATE  	DEF_SET_BIT1 
#define	ICON_SET_COOL 	DEF_SET_BIT2
   	
#define ICON_CLR_RATE  	DEF_CLR_BIT1 
#define	ICON_CLR_COOL 	DEF_CLR_BIT2

//把连接到数码管脚的IO口配置为输入模式，注意这些引脚不要开启上拉或下拉，引起不必要的麻烦    
#define PIN1_IN()       $ LED_PORT1 in,X_PH;    //对应数码管PIN1 
#define PIN2_IN()       $ LED_PORT2 in,X_PH;    //对应数码管PIN2
#define PIN3_IN()       $ LED_PORT3 in,X_PH;    //对应数码管PIN3
#define PIN4_IN()       $ LED_PORT4 in,X_PH;    //对应数码管PIN4
#define PIN5_IN()       $ LED_PORT5 in,X_PH;    //对应数码管PIN5
 
//把单片机IO口配置为输出模式，输出低电平
#define PIN1_L()        $ LED_PORT1 out,low;
#define PIN2_L()        $ LED_PORT2 out,low;
#define PIN3_L()        $ LED_PORT3 out,low;
#define PIN4_L()        $ LED_PORT4 out,low;
#define PIN5_L()        $ LED_PORT5 out,low;
 
//把单片机IO口配置为输出模式，输出高电平
#define PIN1_H()        $ LED_PORT1 out,high;
#define PIN2_H()        $ LED_PORT2 out,high;
#define PIN3_H()        $ LED_PORT3 out,high;
#define PIN4_H()        $ LED_PORT4 out,high;
#define PIN5_H()        $ LED_PORT5 out,high;

byte icon_flag = 0;
byte hundreds = 0;   	//百位，0不显示，1仅百分比，2百分比+供电，3-百分比+百位，4全部显示
byte tens = 0;   	   	//十位，10-F，11-不显示
byte unit = 0;   	   	//个位，10-F，11-不显示

/*
*  	百位，百分比，充电指示显示
*  	   	   	   	   	   	BIT3   	BIT2   	BIT1   	BIT0
*  	   	   	   	   	   	B1 	   	C1 	   	I  	   	J
*  	0-不显示  	   	   	 0 	   	 0 	   	 0 	   	 0 	   	0x00
*  	1-百位   	   	   	 1 	   	 1 	   	 0 	   	 0 	   	0x0C
*  	2-百分比  	   	   	 0 	   	 0 	   	 0 	   	 1 	   	0x01  
*  	3-百位+百分比   	  1	   	 1 	   	 0 	   	 1 	   	0x0D 	   	   	   	   	   	   	
*  	4-电量       	   	 0 	   	 0 	   	 1 	   	 0 	   	0x02
*  	5-百位+电量	   	   	  1	   	 1 	   	 1 	   	 0 	   	0x0E
*  	6-百分比+电量   	  0	   	 0 	   	 1 	   	 1 	   	0x03
*  	7-百位+百分比+电量	  1	   	  1	   	 1 	   	 1 	   	0x0F
*/
byte num_hund[8] = {0x00, 0x0C, 0x01,	0x0D, 0x02, 0x0E, 0x03, 0x0F};
/*
*  	十位显示和个位显示
*  	   	   	BIT7   	BIT6   	BIT5   	BIT4   	BIT3   	BIT2   	BIT1   	BIT0
*  	   	   	xx 	   	A2/3   	B2/3   	C2/3   	D2/3   	E2/3   	F2/3   	G2/3
*  	0  	   	   	   	1  	   	1  	   	1  	   	1  	   	1  	   	1  	   	0  	   	0x7E
*  	1  	   	   	   	0  	   	1  	   	1  	   	0  	   	0  	   	0  	   	0  	   	0x60
*  	2  	   	   	   	1  	   	1  	   	0  	   	1  	   	1  	   	0  	   	1  	   	0x6D   	   	   	   	   	   	
*  	3  	   	   	   	1  	   	1  	   	1  	   	1  	   	0  	   	0  	   	1  	   	0x79
*  	4  	   	   	   	0  	   	1  	   	1  	   	0  	   	0  	   	1  	   	1  	   	0x33
*  	5  	   	   	   	1  	   	0  	   	1  	   	1  	   	0  	   	1  	   	1  	   	0x5B
*  	6  	   	   	   	1  	   	0  	   	1  	   	1  	   	1  	   	1  	   	1  	   	0x5F
*  	7  	   	   	   	1  	   	1  	   	1  	   	0  	   	0  	   	0  	   	0  	   	0x70   	   	   	   	   	   	   	
*  	8  	   	   	   	1  	   	1  	   	1  	   	1  	   	1  	   	1  	   	1  	   	0x7F
*  	9  	   	   	   	1  	   	1  	   	1  	   	1  	   	0  	   	1  	   	1  	   	0x7B
*  	F  	   	   	   	1  	   	0  	   	0  	   	0  	   	1  	   	1  	   	1  	   	0x47
*  	not             0  	   	0  	   	0  	   	0  	   	0  	   	0  	   	0  	   	0x00
*/
byte nums[12] = {0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70, 0x7F, 0x7B, 0x47, 0x00};
//熄灭所有数码管
void Set_AllPin_INPUT(void)
{
    PIN1_IN();
    PIN2_IN();
    PIN3_IN();
    PIN4_IN();
    PIN5_IN();

}
 
/*
*  	  | 1  | 2  | 3  | 4  | 5  拉高
*  	1 |    | B3 | D3 | F3 | G3
*  	2 | A3 |    | B2 | D2 | E2
*  	3 | C3 | A2 |    | C2 | F2
*  	4 | E3 | C1 | B1 |    | G2
*  	5 |    | I  | J  |    |  
*  拉低
*/
//1脚拉低，可显示B3 D3 F3 G3
void Display_Scan1(void)
{
    PIN1_L();  	   	   	   	//拉低Pin1
	temp_value = nums[unit];
    if(temp_value & BIT5)  	//B3
       	PIN2_H();
    if(temp_value & BIT3)  	//D3
   	   	PIN3_H();
   	if(temp_value & BIT1)  	//F3
   	   	PIN4_H();
   	if(temp_value & BIT0)  	//G3
   	   	PIN5_H();
}
 
//2脚拉低，可显示A3 B2 D2 E2
void Display_Scan2(void)
{
    PIN2_L();
	temp_value = nums[unit];
    if(temp_value & BIT6)  	//A3
       	PIN1_H();
	temp_value = nums[tens];
   	if(temp_value & BIT5)  	//B2
   	   	PIN3_H();
   	if(temp_value & BIT3)  	//D2
   	   	PIN4_H();
   	if(temp_value & BIT2)  	//E2
   	   	PIN5_H();
}
 
//3脚拉低，可显示C3 A2 C2 F2
void Display_Scan3(void)
{
    PIN3_L();
	temp_value = nums[unit];
    if(temp_value & BIT4)  	//C3
       	PIN1_H();
	temp_value = nums[tens];
   	if(temp_value & BIT6)  	//A2
   	   	PIN2_H();
   	if(temp_value & BIT4)  	//C2
   	   	PIN4_H();
   	if(temp_value & BIT1)  	//F2
   	   	PIN5_H();
}
 
//4脚拉低，可显示E3 C1 B1 G2
void Display_Scan4(void)
{
    PIN4_L();
	temp_value = nums[unit];
    if(temp_value & BIT2)  	   	   	//E3
       	PIN1_H();
	temp_value = num_hund[hundreds];
   	if(temp_value & BIT2)  	//C1
   	   	PIN2_H();
   	if(temp_value & BIT3)  	//B1
   	   	PIN3_H();
	temp_value = nums[tens];
   	if(temp_value & BIT0)  	   	   	//G2
   	   	PIN5_H();
}
 
//5脚拉低，可显示 J(百分比) I（充电）
void Display_Scan5(void)
{
   	PIN5_L();
	temp_value = num_hund[hundreds];
   	if(temp_value & BIT1)  	//I
   	   	PIN3_H();
   	if(temp_value & BIT0)  	//J
   	   	PIN2_H();
}

byte scan_cnt;//逐行扫描
void Display(void)
{
    Set_AllPin_INPUT();//消影作用
 
    switch(scan_cnt)
    {
      case 0:Display_Scan1();scan_cnt++;break;
      case 1:Display_Scan2();scan_cnt++;break;
      case 2:Display_Scan3();scan_cnt++;break;
      case 3:Display_Scan4();scan_cnt++;break;
      case 4:Display_Scan5();scan_cnt=0;break;
      default:scan_cnt=0;break;
    }
}

/*****************************************************************************
@brief 	:  	Digit separate
@param    
@retval	    
******************************************************************************/
void Digit_Separate(byte num, byte icon_bit, byte num_high_flag)
{
   	byte number_bit[3];
   	byte num_temp = 0;
   	byte i = 0;

	if(num == 0xff)
	{
		icon_flag = 0;
		hundreds = 0;  	
		tens = 11;  	   	//十位，10-F，11-不显示
		unit = 11;  	   	//个位，10-F，11-不显示

		return;
	}

   	while(i < 3)
   	{
   	   	num_temp = num;
   	   	while(num_temp > 9)
   	   	{
   	   	   	num_temp = num_temp - 10;
   	   	}
   	   	number_bit[i] = num_temp;
		div_src4 = num; //被除数
		div_val2 = 10; //除数
		DWord_Div_Word();
		num = div_src4;
   	   	i++;
   	}

	if(num_high_flag == 0)
	{
		if(number_bit[1] == 0)
		{
			number_bit[1] = 0xff;
		}
	}
   	
   	unit = number_bit[0];
   	tens = number_bit[1];
   	hundreds = number_bit[2] | icon_bit; 
}



/********************************************************************************************************************
												Key check
*********************************************************************************************************************/
__LABEL_KEY_CHECK:

#define KEY_NUM					3
#define KEY1_DOUBLE_SHORT_EN	0
#define KEY2_DOUBLE_SHORT_EN	0
#define KEY3_DOUBLE_SHORT_EN	0

#define KEY1_SHORT_PRESS_TIME	70
#define KEY1_LONG_PRESS_TIME	700	
#define KEY1_DOUBLE_INTERVAL	255			

#define KEY2_SHORT_PRESS_TIME	70
#define KEY2_LONG_PRESS_TIME	700	
#define KEY2_DOUBLE_INTERVAL	255	

#define KEY3_SHORT_PRESS_TIME	70
#define KEY3_LONG_PRESS_TIME	700	
#define KEY3_DOUBLE_INTERVAL	300	

#if (KEY_NUM >= 1)
KEY1_IO	=> PA.7
#endif
#if (KEY_NUM >= 2)
KEY2_IO	=> PA.6
#endif
#if (KEY_NUM >= 3)
KEY3_IO	=> PB.6
#endif
/*****************************************************************************
@brief	：KEY IO initailazation
@param    
@retval	    
******************************************************************************/
void Key_IO_Init(void)
{
#if (KEY_NUM >= 1)
	$ KEY1_IO in,pull;	
#endif
#if (KEY_NUM >= 2)
	$ KEY2_IO in,pull;	
#endif
#if (KEY_NUM >= 3)
	$ KEY3_IO in,pull;	
#endif
}

/*****************************************************************************
@brief	：keys check
@param    
@retval	    
******************************************************************************/
#if (KEY_NUM >= 1)
word key_bits = 0;
bit key1_prevent : key_bits.0;
#if (KEY1_DOUBLE_SHORT_EN == 0)
bit key1_short_press  : key_bits.1;
#else 
byte key1_short_press = 0;
#endif
bit key1_long_press : key_bits.2;
byte key1_two_press_count = 0;
byte key1_two_press_time = 0;
word hard_key1_count = 0;
#endif
#if (KEY_NUM >= 2)
bit key2_prevent : key_bits.3;
#if (KEY2_DOUBLE_SHORT_EN == 0)
bit key2_short_press : key_bits.4;
#else
byte key2_short_press = 0;
#endif
bit key2_long_press : key_bits.5;
byte key2_two_press_count = 0;
byte key2_two_press_time = 0;
word hard_key2_count = 0;
#endif
#if (KEY_NUM >= 3)
bit key3_prevent : key_bits.6;
#if (KEY3_DOUBLE_SHORT_EN == 0)
bit key3_short_press : key_bits.7;
#else
byte key3_short_press = 0;
#endif
bit key3_long_press : key_bits.8;
byte key3_two_press_count = 0;
word key3_two_press_time = 0;
word hard_key3_count = 0;
#endif
byte long_press_exe_interval = 0;

void Ckeck_TK_KEY_Status(void)
{
	/* key1 */
#if (KEY_NUM >= 1)
	if(KEY1_IO == 0)
	{
		check_adc_delay = 250;
		sleep_time_count = 5000; //有按键按下禁止休眠

		if(key1_prevent == 0)
		{
			hard_key1_count++;
			if(hard_key1_count > KEY1_LONG_PRESS_TIME) //1000ms
			{
				key1_long_press = 1;
				key1_prevent = 1;   	//prevent long press circulate execute
				hard_key1_count = 0;
			}
		}
	}
	else
	{
		if(hard_key1_count > KEY1_SHORT_PRESS_TIME) //60ms
		{
			key1_short_press = 1;
		}
		hard_key1_count = 0;
		key1_prevent = 0;
		key1_long_press = 0;
	}

	/**************************************************key1 tow press check**********************************************/
#if (KEY1_DOUBLE_SHORT_EN == 1)
	if(key1_short_press == 1) //once short press
	{
		key1_short_press = 0;
		key1_two_press_count++;
		key1_two_press_time = KEY1_DOUBLE_INTERVAL; //300ms interval
	}

	if(key1_two_press_time > 0)
	{
		key1_two_press_time--;
	}

	if(key1_two_press_time == 0 || key1_two_press_count == 2) //wait two press check time end or two press occur
	{
		if(key1_two_press_count == 1)
		{
			key1_short_press = 2;
		}
		else if(key1_two_press_count == 2)
		{
			key1_short_press = 3;
		}

		key1_two_press_count = 0;
		key1_two_press_time = 0;
	}
	
#endif

#endif
	/* key2 */
#if (KEY_NUM >= 2)
	if(KEY2_IO == 0)
	{
		check_adc_delay = 250;
		sleep_time_count = 5000; //有按键按下禁止休眠

		if(key2_prevent == 0)
		{
			hard_key2_count++;
			if(hard_key2_count > KEY2_LONG_PRESS_TIME)
			{
				key2_long_press = 1;
				key2_prevent = 1;   	//prevent long press circulate execute
				hard_key2_count = 0;
			}
		}
	}
	else
	{
		if(hard_key2_count > KEY2_SHORT_PRESS_TIME)
		{
			key2_short_press = 1;
		}
		hard_key2_count = 0;
		key2_prevent = 0;
		key2_long_press = 0;
	}

	/**************************************************key2 tow press check**********************************************/
#if (KEY2_DOUBLE_SHORT_EN == 1)
	if(key2_short_press == 1) //once short press
	{
		key2_short_press = 0;
		key2_two_press_count++;
		key2_two_press_time = KEY2_DOUBLE_INTERVAL;
	}

	if(key2_two_press_time > 0)
	{
		key2_two_press_time--;
	}

	if(key2_two_press_time == 0 || key2_two_press_count == 2) //wait two press check time end or two press occur
	{
		if(key2_two_press_count == 1)
		{
			key2_short_press = 2;
		}
		else if(key2_two_press_count == 2)
		{
			key2_short_press = 3;
		}

		key2_two_press_count = 0;
		key2_two_press_time = 0;
	}
	
#endif
#endif

	/* key3 */
#if (KEY_NUM >= 3)
	if(KEY3_IO == 0)
	{
		check_adc_delay = 250;
		if(key3_prevent == 0)
		{
			hard_key3_count++;
			if(hard_key3_count > KEY3_LONG_PRESS_TIME)
			{
				key3_long_press = 1;
				key3_prevent = 1;   	//prevent long press circulate execute
				hard_key3_count = 0;
			}
		}
	}
	else
	{
		if(hard_key3_count > KEY3_SHORT_PRESS_TIME)
		{
			key3_short_press = 1;
		}
		hard_key3_count = 0;
		key3_prevent = 0;
		key3_long_press = 0;
	}

	/**************************************************key3 tow press check**********************************************/
#if (KEY3_DOUBLE_SHORT_EN == 1)
	if(key3_short_press == 1) //once short press
	{
		key3_short_press = 0;
		key3_two_press_count++;
		key3_two_press_time = KEY3_DOUBLE_INTERVAL;
	}

	if(key3_two_press_time > 0)
	{
		key3_two_press_time--;
	}

	if(key3_two_press_time == 0 || key3_two_press_count == 2) //wait two press check time end or two press occur
	{
		if(key3_two_press_count == 1)
		{
			key3_short_press = 2;
		}
		else if(key3_two_press_count == 2)
		{
			key3_short_press = 3;
		}

		key3_two_press_count = 0;
		key3_two_press_time = 0;
	}
#endif
#endif

}
/*****************************************************************************
@brief 	：key short press logic process
@param    
@retval	    
******************************************************************************/
void Key_Short_Process(void)
{
#if (KEY_NUM >= 1)
#if (KEY1_DOUBLE_SHORT_EN == 0)
	if(key1_short_press == 1)
	{
		key1_one_flag = 1;

		
		key1_short_press = 0;
	}
#else
	if(key1_short_press == 2)  	// 单击
	{
		

		key1_short_press = 0;
	}

	if(key1_short_press == 3)  	// 双击
   	{
		key1_double_flag = 1;
		
   	   	key1_short_press = 0;
   	}
#endif
#endif

#if (KEY_NUM >= 2)
#if (KEY2_DOUBLE_SHORT_EN == 0)
	if(key2_short_press == 1)
	{
		key2_one_flag = 1;
		 
		key2_short_press = 0;
	}
#else
	if(key2_short_press == 2)  	// 单击
	{
		

		key2_short_press = 0;
	}

	if(key2_short_press == 3)  	// 双击
   	{
		key2_double_flag = 1;
		
   	   	key2_short_press = 0;
   	}
#endif
#endif	

#if (KEY_NUM >= 3)
#if (KEY3_DOUBLE_SHORT_EN == 0)
	if(key3_short_press == 1)
	{
		key3_one_flag = 1;

		key3_short_press = 0;
	}
#else
	if(key3_short_press == 2)
	{

		
		key3_short_press = 0;
	}

	if(key3_short_press == 3)
	{

		
		key3_short_press = 0;
	}
#endif
#endif	

	
}

/*****************************************************************************
@brief 	：key short press logic process
@param    
@retval	    
******************************************************************************/
void Key_Long_Process(void)
{
#if (KEY_NUM >= 1)
	/* 按键1长按处理 */
	if(key1_long_press == 1)
	{
		if(long_press_exe_interval == 0)
   	   	{
   	   	   	long_press_exe_interval = 60;
   	   	   	key1_long_flag = 1;
			fan_check_count = 250;
   	   	}
		
	}
#endif

#if (KEY_NUM >= 2)
	/* 按键2长按处理 */
	if(key2_long_press == 1)
	{
		temp_count = 0;
		if(power_alarm == 1)
		{
			/* 电池没电了 */
			temp_count = 3;
			while(temp_count--)
			{
				hundreds = 0;  	
				tens = 0;  	   	//十位，10-F，11-不显示
				unit = 0;  	   	//个位，10-F，11-不显示
				Delay_ms(500);
				hundreds = 0;  	
				tens = 11;  	   	//十位，10-F，11-不显示
				unit = 11;  	   	//个位，10-F，11-不显示
				Delay_ms(500);	

				sleep_time_count = 5000;
			}
		}
		else
		{
			key2_long_flag = 1;
		}

		key2_long_press = 0;
	}
#endif

#if (KEY_NUM >= 3)
	if(key3_long_press == 1)
	{
		if(long_press_exe_interval == 0)
   	   	{
   	   	   	long_press_exe_interval = 60;
   	   	   	key3_long_flag = 1;
   	   	}

	}

#endif

}


/********************************************************************************************************************
														ADC
*********************************************************************************************************************/

/*****************************************************************************
@brief 	：ADC初始化
@param    
@retval	    
******************************************************************************/
// word	data;//分辨率为12测得的ADC值
word	VDD_data;
word	BG_data;
void	ADC_BG_init(void)//初始化
{
	$ ADCC	Enable,BANDGAP;	//启用ADC功能，通道选择BANDGAP（AD转换的输入信号）
						//启用：Enable；停用：Disable
	$ ADCM	/8;			//时钟源选择（系统时钟/X）
						//X有/1, /2, /4, /8, /16, /32, /64, /128
						//注：时钟源选择建议选用500K（/2）
						//参考高电压为VDD
	.delay 400;			//延时400us
						//注：时钟源选择其他时，延迟时间请参考datasheet
}

void ADC_IO_init(void)//初始化
{
	//注：选择的通道需设置为输入，无上拉、下拉电阻、无数字输入使能；
	PBC.0 = 0;
	PBPH.0 = 0;
	PBPL.0 = 0;			//无下拉的脚位不需要这条指令
	PBDIER = 0b1111_1110;//注：其他脚默认为1，需要关闭的请手动修改
//	$ PADIER 0b1110_1001;//上面语法错误可用这条替代
	$ ADCC	Enable,PB0;	//启用ADC功能，通道选择（AD转换的输入信号）
						//启用：Enable；停用：Disable
						//通道选择：PB0, PB1, PB2, PB3, PB4, PB5, PB6, PB7,PA3, PA4, PA0
						//注：每个芯片的待测脚位不同，详情参考datasheet
	$ ADCM	/8;			//时钟源选择（系统时钟/X）
						//X有/1, /2, /4, /8, /16, /32, /64, /128
						//注：时钟源选择建议选用500K（/2）
						//参考高电压为VDD
	.delay 400;			//延时400us
						//注：时钟源选择其他时，延迟时间请参考datasheet
}

/*****************************************************************************
@brief 	：ADC测量平均值
@param    
@retval	    
******************************************************************************/
void	ADC_mea(void)
{
	//开始ADC转换
	AD_START = 1;		//开始ADC转换
	while(!AD_DONE)		//等待ADC转换结果
		NULL;
	//当AD_DONE高电位时读取ADC结果
	temp_value32$1 = ADCRH;temp_value32$0 = ADCRL;		//将ADC的值赋给data
	temp_value32 = temp_value32 >> 4;	//12 bit ADC
}

/*****************************************************************************
@brief 	：ADC Process
@param    
@retval	    
******************************************************************************/
void ADC_Process(void)
{
	/* ADC pick and average */
	ADC_BG_init();
	ADC_mea();
	BG_data = temp_value32;
	//-------------------------------------------
	mul_x2 = 0xFFF;//分辨率12为0xFFF0
	mul_y2 = 1200;//BG电压的1000倍
	Word_Mul_Word();
	div_src4 = mul_t4; //被除数
	div_val2 = temp_value32; //除数
	DWord_Div_Word();
	VDD_data = div_src4;
	// Print_U16_Line('B', VDD_data);
}

void ADC_IO_Process(void)
{
	/* ADC pick and average */
	ADC_BG_init();
	ADC_mea();
	BG_data = temp_value32;
	ADC_IO_init();
	ADC_mea();
	VDD_data = temp_value32;
	//-------------------------------------------
	mul_x2 = VDD_data;//分辨率12为0xFFF0
	mul_y2 = 1200;//BG电压的1000倍
	Word_Mul_Word();
	div_src4 = mul_t4; //被除数
	div_val2 = BG_data; //除数
	DWord_Div_Word();
	VDD_data = div_src4;
}

/*****************************************************************************
@brief 	：voltage pick
@param    
@retval	    
******************************************************************************/
void Battry_Voltage_Pick(void)
{
	ADC_Process(); //

	/* power on pick battery voltage */
	battery_voltage_rate = VDD_data;
	if(battery_voltage_rate < 3300)
	{
		battery_voltage_rate = 3300;
	}
	if(battery_voltage_rate > 4100)
	{
		battery_voltage_rate = 4100;
	}
	battery_voltage_rate = battery_voltage_rate - 3300;
	div_src4 = battery_voltage_rate; //被除数
	div_val2 = 8; //除数
	DWord_Div_Word();
	battery_voltage_rate = div_src4;
	
	// Print_U16_Line('B', battery_voltage_rate);
	
}


/********************************************************************************************************************
   	   	   	   	   	   	   	   	   	   	charge and discharge process
*********************************************************************************************************************/
/*****************************************************************************
@brief 	：power show
@param    
@retval	    
******************************************************************************/
void Power_Show_Process(void)
{
	/* 耗电 */
	if((work_gear_num) && charge_status == 0)
	{
	   	if(battery_voltage_rate > 0) //if power empty
	   	{
			if(battery_voltage_rate < 10)
			{
				/* 低压警告 */
				power_alarm = 2;
			}

	   	   	if(reload_consume_power_back != reload_consume_power_interval)
	   	   	{
	   	   	   	//if reload value be changed so record value
	   	   	   	reload_consume_power_back = reload_consume_power_interval;
				consume_power_interval_count = reload_consume_power_interval;
	   	   	}
	   	   	if(consume_power_interval_count == 0)
	   	   	{
	   	   	   	consume_power_interval_count = reload_consume_power_interval;
	   	   	   	battery_voltage_rate--;
	   	   	}
	   	}
	   	else 
	   	{
	   	   	//power empty
	   	   	if(power_alarm != 1)
	   	   	{
				temp_count = 3;
				while(temp_count--)
				{
					hundreds = 0;  	
					tens = 0;  	   	//十位，10-F，11-不显示
					unit = 0;  	   	//个位，10-F，11-不显示
					Delay_ms(500);
					hundreds = 0;  	
					tens = 11;  	   	//十位，10-F，11-不显示
					unit = 11;  	   	//个位，10-F，11-不显示
					Delay_ms(500);	
				}

	   	   	   	power_alarm = 1;
	   	   	   	work_gear_num = 0; 	
				update_gear_flag = 1;
	   	   	   	sleep_time_count = 5000; //
	   	   	   	reload_consume_power_back = 0; //下次插上充电器重置充电时间
	   	   	}
	   	}  	
	}

	/* 充电 */
	if(POWER_VCC_CHECK_IO)
	{
	   	power_alarm = 0; //clear

	   	if(work_gear_num) 
	   	{
	   	   	if(charge_status != 1)
	   	   	{
				if(charge_status == 0)
				{
					gear_show_time = 0;
				}
				else
				{
					gear_show_time = 5000;
				}
				charge_status = 1;
				charge_power_interval_count = 162000; // 162000 4.5h
				charge_status_flag = 1; //充电状态更新标记
	   	   	}
	   	}
	   	else
	   	{
	   	   	if(charge_status != 2) 
	   	   	{
				charge_status = 2;
				charge_power_interval_count = 108000; //108000 3h
				charge_status_flag = 1; //充电状态更新标记
	   	   	}
	   	}

		if(charge_power_interval_count == 0) //每隔充电电量时间到了
		{
			if(charge_status == 1)
			{
				charge_power_interval_count = 162000; // 162000 4.5h
			}
			else if(charge_status == 2)
			{
				charge_power_interval_count = 108000; //108000 3h
			}
			if(battery_voltage_rate < 100)
			{
				battery_voltage_rate++;
			}
		}
	}
	else
	{
	   	if(charge_status)
	   	{
	   	   	charge_status = 0;
			charge_status_flag = 1; //充电状态更新标记
			sleep_time_count = 5000;
	   	}
	}

	/* 电量显示 */
	if(power_alarm == 0 && (work_gear_num || charge_status))
	{
	   	if(charge_status == 0)
	   	{
	   	   	if(blink_interval == 0)
	   	   	{
	   	   	   	blink_interval = 500; //500ms

				if(gear_show_time == 0) //档位显示时间结束
				{
					if(cool_work_mode)
					{
						icon_flag |= ICON_SET_COOL;
					}
					else
					{
						icon_flag &= ICON_CLR_COOL;
					}
					icon_flag |= ICON_SET_RATE;
	   	   	   		Digit_Separate(battery_voltage_rate, icon_flag, 1);
				}
				else
				{
					if(cool_work_mode)
					{
						icon_flag |= ICON_SET_COOL;
					}
					else
					{
						icon_flag &= ICON_CLR_COOL;
					}
					icon_flag &= ICON_CLR_RATE;
	   	   	   		Digit_Separate(work_gear_num, icon_flag, 1);
				}
	   	   	}
	   	}
   	   	
	   	if(charge_status)
	   	{
	   	   	if(battery_voltage_rate < 100) //not charge full
	   	   	{
				if(blink_interval == 0)
				{
					if(gear_show_time == 0)
					{
						blink_interval = 500; //500ms
						if(blink_flag == 0)
						{
							blink_flag = 1;

							icon_flag |= ICON_SET_RATE;
							icon_flag &= ICON_CLR_COOL;
							Digit_Separate(battery_voltage_rate, icon_flag, 1);
						}
						else
						{
							blink_flag = 0;

							icon_flag &= ICON_CLR_RATE;
							icon_flag &= ICON_CLR_COOL;
							Digit_Separate(battery_voltage_rate, icon_flag, 1);
						}
					}
					else
					{
						icon_flag &= ICON_CLR_RATE;
						icon_flag &= ICON_CLR_COOL;
						Digit_Separate(work_gear_num, icon_flag, 1);
					}
				}
	   	   	   	
	   	   	}
	   	   	else
	   	   	{
				if(blink_interval == 0)
				{
					blink_interval = 100; //100ms

					if(gear_show_time == 0)
					{
						icon_flag |= ICON_SET_RATE;
						icon_flag &= ICON_CLR_COOL;
						Digit_Separate(battery_voltage_rate, icon_flag, 1);
					}
					else
					{
						icon_flag &= ICON_CLR_RATE;
						icon_flag &= ICON_CLR_COOL;
						Digit_Separate(work_gear_num, icon_flag, 1);
					}
				}
	   	   	}
	   	}
	}

	/* 报警提示 */
	if(power_alarm == 2 && work_gear_num)
	{
		if(blink_interval == 0)
		{
			blink_interval = 500; //500ms

			if(gear_show_time == 0) //档位显示时间结束
			{
				
				if(blink_flag == 0)
				{
					blink_flag = 1;

					if(cool_work_mode)
					{
						icon_flag |= ICON_SET_COOL;
					}
					else
					{
						icon_flag &= ICON_CLR_COOL;
					}
					icon_flag |= ICON_SET_RATE;
					Digit_Separate(battery_voltage_rate, icon_flag, 1);
				}
				else
				{
					blink_flag = 0;

					if(cool_work_mode)
					{
						icon_flag |= ICON_SET_COOL;
					}
					else
					{
						icon_flag &= ICON_CLR_COOL;
					}
					icon_flag |= ICON_SET_RATE;
					hundreds = icon_flag;  	
					tens = 11;  	   	//十位，10-F，11-不显示
					unit = 11;  	   	//个位，10-F，11-不显示
				}
			}
			else
			{
				if(cool_work_mode)
				{
					icon_flag |= ICON_SET_COOL;
				}
				else
				{
					icon_flag &= ICON_CLR_COOL;
				}
				icon_flag &= ICON_CLR_RATE;
				Digit_Separate(work_gear_num, icon_flag, 1);
			}
		}
	}
}


/********************************************************************************************************************
												Mian function processing
*********************************************************************************************************************/
/*****************************************************************************
@brief 	：sleep mode
@param    
@retval	    
******************************************************************************/
void	Power_down(void)
{
	//======User can add code=====
	//进入省电模式前动作，如关灯、关计数器等
	// $ POWER_CHARGE_CHECK_IO out,low;
	// $ FAN_INSTALL_FB_IO out,high;
	// Delay_ms(10);
	//============================

	byte	POWER_CLKMD_BK;
	POWER_CLKMD_BK = CLKMD;					//保存休眠前的时钟
	PADIER = 0b1110_0000;				//将PAx设置为数字模式
	PBDIER = 0b0100_0001;				//将PBx设置为数字模式
	//休眠前需要切换低频ILRC用来防止唤醒失败
	$ CLKMD ILRC/1,En_IHRC,En_ILRC;		//系统时钟选择，是否启用IHRC，是否启用ILRC，（En_IHRC和En_ILRC不写为停用，写为启用）
										//系统时钟可选择IHRC/4, IHRC/16, IHRC/2, IHRC/8, ILRC/16, EOSC/4, IHRC/32, EOSC/2, IHRC/64, EOSC/1, EOSC/8, ILRC/4, ILRC/1
										//选择系统时钟为ILRC/1，启用ILRC和IHRC；（注：两个RC振荡器至少有一个开启，否则会出现宕机）
	CLKMD.En_IHRC = 0;					//关闭高频IHRC，若上条语句没使用低频时钟，此句必须去掉
	nop;
	while(1)
	{
		stopsys;						//进入断电模式
	//=======编写唤醒条件=========
		//例如PA0由高变低唤醒，该方法针对IO脚电平变化的唤醒条件
		//if(!PA.7 || !PA.6 || !PA.5 || !PB.5 || !PB.0 || PB.0)						//假如发生唤醒而且检查OK，就返回正常工作
		//{								//否则停留在断电模式
			break;
		//}
	}
	$ CLKMD ILRC/1,EN_IHRC,EN_ILRC;		//打开高频使能，准备切换回系统时钟
	nop;
	CLKMD = POWER_CLKMD_BK;					//恢复休眠前的时钟

	//======User can add code=====
	//唤醒后打开需要的动作，比如开灯、定时器等
	// $ POWER_CHARGE_CHECK_IO in;
	// $ FAN_INSTALL_FB_IO in;

	//============================	
}

/*****************************************************************************
@brief 	：Main function
@param    
@retval	    
******************************************************************************/
void	FPPA0 (void)
{
	.ADJUST_IC	SYSCLK=IHRC/4, IHRC=16MHz, VDD=4V;
	
	IO_init();
	Key_IO_Init();
	T16_Init();
	TM2_PWM();

	ENGINT;						//打开全局中断 DISGINT

	/* power on show */
	hundreds = 7;  	
	tens = 8;  	   	//十位，10-F，11-不显示
	unit = 8;  	   	//个位，10-F，11-不显示
	Delay_ms(500);
	hundreds = 0;  	
	tens = 11;  	   	//十位，10-F，11-不显示
	unit = 11;  	   	//个位，10-F，11-不显示
	Delay_ms(500);	

	/* ADC pick and average */
	Battry_Voltage_Pick();
	// battery_voltage_rate = 0;
	sleep_time_count = 1000; //
	// reload_consume_power_interval = 576000; //16h

	byte i = 0;
	while (1)
	{
		/* 按键处理 */
		Key_Short_Process();
		Key_Long_Process();    

		/* 电量显示 */
		Power_Show_Process();

		/* 电池低压检测&风扇负载检测 */
		if(fan_check_count == 0 && work_gear_num)
		{
			fan_check_count = 200; //200ms

			/* 风扇负载检测 */
			if(FAN_INSTALL_FB_IO)
			{
				fan_not_check_num++;
				if(fan_not_check_num > 10)
				{
					work_gear_num = 0;
					update_gear_flag = 1;
					fan_not_check_num = 0;
					sleep_time_count = 5000; //
				}
			}
			else
			{
				fan_not_check_num = 0;
			}

			/* 电池低压检测 */
			/* ADC pick and average */
			ADC_Process(); //
			if(VDD_data < 2800 && check_adc_delay == 0)
			{
				fan_low_check_num++;
				if(fan_low_check_num > 10)
				{
					temp_count = 3;
					while(temp_count--)
					{
						hundreds = 0;  	
						tens = 0;  	   	//十位，10-F，11-不显示
						unit = 0;  	   	//个位，10-F，11-不显示
						Delay_ms(500);
						hundreds = 0;  	
						tens = 11;  	   	//十位，10-F，11-不显示
						unit = 11;  	   	//个位，10-F，11-不显示
						Delay_ms(500);	
					}

					work_gear_num = 0;
					update_gear_flag = 1;
					battery_voltage_rate = 0;
					fan_low_check_num = 0;
					power_alarm = 1; //
					sleep_time_count = 5000;
				}
			}
			else
			{
				fan_low_check_num = 0;
			}
		}

		/* 状态机 */
		if(	key1_one_flag || key2_one_flag || key3_one_flag ||
			key1_long_flag || key2_long_flag || key3_long_flag || 
			charge_status_flag || update_gear_flag || update_consume_time_flag)
		{
			/* 短按 */
			if(key1_one_flag) //
			{
				if(fan_open_flag)
				{
					if(work_gear_num < 20)
					{
						work_gear_num = 20;
					}
					else if(work_gear_num < 40)
					{
						work_gear_num = 40;
					}
					else if(work_gear_num < 60)
					{
						work_gear_num = 60;
					}
					else if(work_gear_num < 80)
					{
						work_gear_num = 80;
					}
					else
					{
						work_gear_num = 100;
					}
					// if(cool_work_mode)
					// {
					// 	if(work_gear_num > GEAR_LIMIT_NUM40)
					// 	{
					// 		work_gear_num = GEAR_LIMIT_NUM40;
					// 		update_gear_flag = 1; //需要更新挡位
					// 	}
					// }
					update_gear_flag = 1;
				}
				
				key1_one_flag = 0;
			}
			if(key2_one_flag) /* 制冷片开关机 */
			{
				if(charge_status == 0 && work_gear_num) //充电或者风扇没开启时不能开启制冷
				{
					update_consume_time_flag = 1;
					if(cool_work_mode)
					{
						cool_work_mode = 0;
						COOL_SWITCH_IO = 0;
					}
					else
					{
						cool_work_mode = 1;
						COOL_SWITCH_IO = 1;
						// if(work_gear_num > GEAR_LIMIT_NUM40)
						// {
						// 	work_gear_num = GEAR_LIMIT_NUM40;
						// 	update_gear_flag = 1; //需要更新挡位
						// }

					}
					blink_flag = 0;
					blink_interval = 0; 
				}
				update_gear_flag = 1;

				key2_one_flag = 0;
			}
			if(key3_one_flag) //
			{
				if(fan_open_flag)
				{
					if(work_gear_num > 80)
					{
						work_gear_num = 80;
					}
					else if(work_gear_num > 60)
					{
						work_gear_num = 60;
					}
					else if(work_gear_num > 40)
					{
						work_gear_num = 40;
					}
					else if(work_gear_num > 20)
					{
						work_gear_num = 20;
					}
					else
					{
						work_gear_num = 1;
					}
					update_gear_flag = 1;
				}
				
				key3_one_flag = 0;
			}
			/* 长按 */
			if(key1_long_flag) //
			{
				if(fan_open_flag)
				{
					if(work_gear_num < GEAR_TO_NUM100)
					{
						work_gear_num++;
						// if(cool_work_mode)
						// {
						// 	if(work_gear_num > GEAR_LIMIT_NUM40)
						// 	{
						// 		work_gear_num = GEAR_LIMIT_NUM40;
						// 		update_gear_flag = 1; //需要更新挡位
						// 	}
						// }
						
					}
					update_gear_flag = 1;
				}

				key1_long_flag = 0;
			}
			if(key2_long_flag) //
			{
				if(fan_open_flag == 0)
				{
					fan_open_flag = 1;
					if(record_work_gear == 0)
					{
						work_gear_num = GEAR_TO_NUM1;
						update_gear_flag = 1; //需要更新挡位
					}
					else
					{
						work_gear_num = record_work_gear;
						// if(cool_work_mode)
						// {
						// 	if(work_gear_num > GEAR_LIMIT_NUM40)
						// 	{
						// 		work_gear_num = GEAR_LIMIT_NUM40;
						// 		update_gear_flag = 1; //需要更新挡位
						// 	}
						// }
					}
					FAN_ENABLE_IO = 1;
					Delay_ms(50);
					$ TM2C IHRC*2,PWM_SET_IO,PWM; //打开PWM
				}
				else
				{
					fan_open_flag = 0;
					// record_work_gear = work_gear_num;
					work_gear_num = GEAR_TO_NUM0; //
					update_gear_flag = 1;
				}

				key2_long_flag = 0;
			}
			if(key3_long_flag)
   	   		{
				if(fan_open_flag)
				{
					if(work_gear_num > GEAR_TO_NUM1)
					{
						work_gear_num--;
					}
					update_gear_flag = 1;
				}
				
				key3_long_flag = 0;
   	   		}

			/* 充电状态 */
			if(charge_status_flag)
			{
				if(charge_status == 0)
				{
					/* 充电器断开 */
					update_gear_flag = 1; //需要更新挡位
				}
				else if(charge_status == 1)
				{
					/* 边充边用 */
					blink_flag = 0;
					blink_interval = 0; 

					/* 边充边用时需要处理的操作 */
					if(cool_work_mode)
					{
						cool_work_mode = 0;
						COOL_SWITCH_IO = 0;
					}

				}
				else if(charge_status == 2)
				{
					/* 关机充电 */
					gear_show_time = 0;
					blink_flag = 0;
					blink_interval = 0; //
				}

				charge_status_flag = 0;
			}
			
			if(update_gear_flag)
			{
				update_consume_time_flag = 1;
				if(work_gear_num)
				{
					/* 调速 */
					mul_x2 = work_gear_num;	
					mul_y2 = 100;				//放大100
					Word_Mul_Word();
					div_src4 = mul_t4; 	 		//被除数
					div_val2 = GEAR_PWM_NUM;	//除数
					DWord_Div_Word();
					record_pwm = 18 + div_src4; //max 18 + 60
					TM2B = record_pwm;
					/* 掉电时间 */
					mul_x2 = work_gear_num;	
					mul_y2 = 5040;				//放大100
					Word_Mul_Word();
					reload_consume_power_interval = 576000 - mul_t4;
					reload_consume_power_back = 0; //更新掉电速度
					fan_open_flag = 1;	//开机状态
				}
				else
				{
					/* 关机 */
					fan_open_flag = 0; //关机状态
					work_gear_num = 0;
					cool_work_mode = 0;
					COOL_SWITCH_IO = 0;
					icon_flag = 0;

					hundreds = 0;  	
					tens = 11;  	   	//十位，10-F，11-不显示
					unit = 11;  	   	//个位，10-F，11-不显示
					
					while(record_pwm)
					{
						record_pwm--;
						TM2B = record_pwm;
						Delay_ms(10);
					}
					$ TM2C STOP;
					FAN_PWM_IO = 0;
					Delay_ms(50);
					FAN_ENABLE_IO = 0;
					
					
					sleep_time_count = 5000; //
				}
				gear_show_time = 5000;
				blink_interval = 0;
				blink_flag = 0;

				update_gear_flag = 0;
			}

			/* 更新掉电时间 */
			if(update_consume_time_flag)
			{
				if(charge_status == 0)
				{
					temp_value32 = 0;
					if(work_gear_num)
					{
						mul_x2 = work_gear_num;	//100
						mul_y2 = 110; // 
						Word_Mul_Word();
						temp_value32 = 2500 + mul_t4; 
					}
					if(cool_work_mode == 1)
					{
						temp_value32 += 8000;
					}

					// Print_U16_Line('T', (temp_value32 & 0xffff));
					// Print_U16_Line('M', ((temp_value32 & 0xffff0000) >> 16));

					if(temp_value32 == 0)
					{
						/* 全部设备关闭 */
						reload_consume_power_interval = 0xffffff;
						reload_consume_power_back = 0; //更新掉电速度
					}
					else
					{
						// 电池容量 * 1000倍 / 耗电电流 * 10倍 = 小时单位工作时间 * 100倍
						// 小时单位工作时间10倍 * 60 * 60 * 100 = 毫秒单位工作时间
						// 毫秒单位工作时间 / 100 = 掉电百分比时间

						div_src4 = 3000000; //电池容量 * 1000
						div_val2 = temp_value32; //耗电电流
						DWord_Div_Word();
						temp_value32 = div_src4; //工作小时数

						// Print_U16_Line('T', (temp_value32 & 0xffff));
						// Print_U16_Line('M', ((temp_value32 & 0xffff0000) >> 16));

						mul_x2 = temp_value32;//小时单位工作时间
						mul_y2 = 360; // 60 * 60 * 1000 / 10 / 1000
						Word_Mul_Word();
						temp_value32 = mul_t4; 

						// Print_U16_Line('T', (temp_value32 & 0xffff));
						// Print_U16_Line('M', ((temp_value32 & 0xffff0000) >> 16));

						reload_consume_power_interval = temp_value32;
						reload_consume_power_back = 0; //更新掉电速度
					}
				}
				update_consume_time_flag = 0;
			}
		}
		else
		{
			/* 准备关机时清除状态 */
			key1_one_flag = 0;
			key1_long_flag = 0;
			key2_one_flag = 0;
			key2_long_flag = 0;
			key3_one_flag = 0;
			key3_long_flag = 0;
			update_gear_flag = 0;
		}


		// /* sleep */
		if(sleep_time_count == 0 && work_gear_num == 0 && charge_status == 0)
		{
			Power_down();
			sleep_time_count = 5000; //
		}
	}
}


/********************************************************************************************************************
													interrupt
*********************************************************************************************************************/

/*****************************************************************************
@brief 	：interrupt processing
@param    
@retval	    
******************************************************************************/
void	Interrupt (void)
{
	pushaf;

	if (Intrq.T16)
	{	//	T16 Trig
		//	User can add code
		stt16 reload_T16;		//设定计数器初始值reload_T16  1000us
			
		// PA.6 = 1;
		// PA.6 = 0;
		
		if(delay_time_count)
		{
			delay_time_count--;
		}
		if(long_press_exe_interval)
		{
			long_press_exe_interval--;
		}
		if(blink_interval)
		{
			blink_interval--;
		}
		if(gear_show_time)
		{
			gear_show_time--;
		}
		if(consume_power_interval_count)
		{
			consume_power_interval_count--;
		}
		if(charge_power_interval_count)
		{
			charge_power_interval_count--;
		}
		if(sleep_time_count)
		{
			sleep_time_count--;
		}
		if(fan_check_count)
		{
			fan_check_count--;
		}
		if(check_adc_delay)
		{
			check_adc_delay--;
		}
		
		Display();
		Ckeck_TK_KEY_Status();
		

		Intrq.T16	=	0;
	}

	popaf;
}